home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
graphics
/
fpoly256.zip
/
FBXBLIT.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-12-17
|
7KB
|
339 lines
TITLE FPBLIT - Fast poly filling blitter
NAME FPBLIT
COMMENT $
Name: FPBLIT
Written and (c) by Dave Stampe 9/11/91
Not for commercial use, so get permission
before marketing code using this stuff!
For private PD use only.
$
COMMENT $
Name: tpoly
Caller: C:
int tpoly(int x1, int x2, long l_incr, long r_incr,
int y1, int y3, int hold);
x1 = left side start, x2 = right side start
if 0x8000, uses end of last poly's side for cont.
y1 = top, y2 = 1+bottom of poly slice
l_incr, r_incr = 2^16 times slope (add to x each line)
hold: 0 = normal, 1 = make sure left is OK
2 = make sure right is OK
(for continuation)
$
.MODEL large
.CODE
; big table more eff. than masking
; start byte lookup table
stmask: REPT 80
db 15,14,12,8
ENDM
; end byte lookup table
fnmask: REPT 80
db 1,3,7,15
ENDM
x1 equ [bp+6] ; arguments to _tpoly
x2 equ [bp+8]
l_incr equ [bp+10]
r_incr equ [bp+14]
y1 equ [bp+18]
y3 equ [bp+20]
hold equ [bp+22]
vline equ [bp-2] ; video base addr. of line
lines equ [bp-4] ; number of lines to fill
clipped equ [bp-6] ; flags clipped poly (needs end recalc)
aswap equ [bp-8]
extrn _l_hold ; holds full res. L, R. point
extrn _r_hold
extrn _t_clip ; clipping rect. sides
extrn _b_clip
extrn _l_clip
extrn _r_clip
extrn _dpaddr ; page base address
;
; tpoly(int x1,int x2, long l_incr, long r_incr,
; int y1, int y3, int hold)
;
PUBLIC _tpoly
_tpoly proc far
.386
push bp
mov bp,sp
sub sp,8
push si
push di
mov word ptr clipped,0
mov ax,word ptr y3 ; if(y3-y1<1)return(-1);
sub ax,word ptr y1
cmp ax,1
jge short continue
mov ax,65535 ; return -1 on bad args
jmp exit
continue:
mov ax,03c5h ; setup DX adr. swap value
mov aswap,ax
cld
mov ax,0a000h ; set video segment
mov es,ax
mov edx,DWORD PTR ds:_l_hold
mov ax,x1
cmp ax,8000h ; old or new left side
je short nlload
mov dx,ax
shl edx,16
add edx,08000h ; force left side to round up
nlload:
mov esi,DWORD PTR ds:_r_hold
mov ax,x2
cmp ax,8000h ; old or new right
je short nrload
mov si,ax
shl esi,16
nrload:
mov bx,y1
cmp bx,WORD PTR ds:_b_clip ; trivial vertical clip tests
jg clipall
mov ax,y3
cmp ax,WORD PTR ds:_t_clip
jle short clipall
cmp ax,WORD PTR ds:_b_clip ; test if next-slice update
jl short okbot ; will be require
inc WORD PTR clipped
mov ax,WORD PTR ds:_b_clip
mov y3,ax
okbot:
; test if top needs clipping
sub bx,WORD PTR ds:_t_clip
jge short oktop
mov ax,WORD PTR ds:_t_clip
mov y1,ax
neg bx ; adjust left, right sides for
movzx ebx,bx ; top of screen
push edx
mov eax,DWORD PTR r_incr ;advance right top
imul eax,ebx
add esi,eax
mov eax,DWORD PTR l_incr ; advance left top
imul eax,ebx
pop edx
add edx,eax
oktop:
mov ax,y3 ; compute # lines
sub ax,y1
jle short clipall ; bad clip trap
mov lines,ax
mov al,y1
mov bl,80 ; compute starting line adr
mul bl
add ax,WORD PTR ds:_dpaddr
mov vline,ax
mov ebx,edx ; convert fixed-pt to integer
sar ebx,16
mov ecx,esi
sar ecx,16
jl short doneline ; preclip left trap
cmp bx,WORD PTR ds:_l_clip ; clip left
jge short iclipl
mov bx,WORD PTR ds:_l_clip
iclipl:
cmp cx,WORD PTR ds:_r_clip ; clip right
jle short nextline
mov cx,WORD PTR ds:_r_clip
jmp short nextline
clipall:
inc WORD PTR clipped ; mark as clipped (none showing)
jmp donetri
nextline:
; start of fast h line blitter:
; bx=left side, cx=right side, vline=line start
xchg dx,aswap
mov al,BYTE PTR cs:[bx+stmask] ; left mask
shr bx,2 ; left address
mov di,cx
mov ah,BYTE PTR cs:[di+fnmask] ; right mask
shr cx,2 ; right address
mov di,vline ; start address
add di,bx
sub cx,bx ; number of bytes-1
je short onebyte
jc short doneline ; clip trap
out dx,al
stosb ; mask first byte
dec cx ; mask rest
mov al,0ffh ; rep faster than test and jmp
out dx,al
rep stosb
mov al,ah
out dx,al
mov es:[di],ah ; mask last byte
jmp short doneline
onebyte:
and al,ah
out dx,al
mov es:[di],al ; single byte mask
doneline:
xchg dx,aswap
add edx,DWORD PTR l_incr ; step left, right edges
add esi,DWORD PTR r_incr
dec WORD PTR lines ; done lines?
jle short donetri
mov ax,80 ; next line address
add vline,ax
mov ebx,edx ; convert fixed pt to integer
sar ebx,16
mov ecx,esi
sar ecx,16
jl short doneline ; left preclip
cmp bx,WORD PTR ds:_l_clip ; clip left edge
jge short nclipl
mov bx,WORD PTR ds:_l_clip
nclipl:
cmp cx,WORD PTR ds:_r_clip ; clip right edge
jle short nextline
mov cx,WORD PTR ds:_r_clip
jmp nextline
donetri: ; finished all drawing
mov edi,edx
test WORD PTR hold,0ffh ; check if L,R pos'ns need
je short nofixup ; fixing because of clipping
test WORD PTR clipped, 0ffh
je short nofixup
mov bx,y3 ; number of lines vertically
sub bx,y1
movzx ebx,bx
test WORD PTR hold,2 ; right update needed?
je short nofixrt ; (use hold flags as this is an
mov eax,DWORD PTR r_incr ; expensive operation)
imul eax,ebx
mov si,x1
shl esi,16
cmp esi,80000000h ; add to old edge or new edge?
jne short rlold
mov esi,DWORD PTR ds:_r_hold
rlold:
add esi,eax
nofixrt:
test WORD PTR hold,1 ; left update needed?
je short nofixup
mov eax,DWORD PTR l_incr
imul eax,ebx
mov di,x2
shl edi,16
add edi,8000h
cmp edi,80008000h ; add to old or new edge?
jne short llold
mov edi,DWORD PTR ds:_l_hold
llold:
add edi,eax
nofixup:
mov DWORD PTR ds:_l_hold,edi ; store edge points in case
mov DWORD PTR ds:_r_hold,esi ; needed for next poly slice
exit:
pop di ; exit code
pop si
mov sp,bp
pop bp
ret
_tpoly endp
;
; long compute_slope(int x1, int y1, int x2, int y2)
;
y1 equ [bp+8]
y2 equ [bp+12]
x1 equ [bp+6]
x2 equ [bp+10]
PUBLIC _compute_slope
_compute_slope proc far
push bp ; computes slope (dy incrementor)
mov bp,sp ; with 16-bit underflow
sub sp,4
.386
xor ecx,ecx
mov cx,y2
sub cx,y1
je short @5@386 ; skip if zero divide (special case)
mov ax,x2 ; detected later by y1==y2 test
sub ax,x1
cwd
movsx eax,ax ; (x2-x1)/(y2-y1)
movsx edx,dx
shl eax,16
idiv ecx
cmp eax,0 ; round up if pos (neg already rounded up)
jle short @5@386
inc eax
@5@386: ; return long value (286 style)
mov [bp-4],eax
mov dx,word ptr [bp-2]
mov ax,word ptr [bp-4]
mov sp,bp
pop bp
ret
_compute_slope endp
end